package cn.pcios.kindle.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.pcios.kindle.db.repository.EpubRepository;
import cn.pcios.kindle.db.repository.MobiRepository;
import cn.pcios.kindle.db.table.Epub;

@Service
public class MultiThreadRead {
	private static final Logger logger = LoggerFactory.getLogger(MultiThreadRead.class); 
	@Autowired
	private EpubRepository dao;
	@Autowired
	private MobiRepository mobidao;
	@Autowired
	private EpubToMobiService epubToDao;

	/**
	 * 获取网络文件大小
	 * 
	 * @param url
	 * @param type
	 * @return
	 * @throws IOException
	 */
	private long getFileLength(String url1) throws IOException {
		TempDb.tix++;
		long length = 0;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpGet httpget = new HttpGet(url1);

		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();// 设置请求和传输超时时间

		httpget.setConfig(requestConfig);

		logger.debug("0.Send the URL to Sina Sever....");
		HttpResponse response = httpclient.execute(httpget);
		HttpEntity entity = response.getEntity();

		logger.debug(TempDb.ttxn + "--1.Get Response Status: " + response.getStatusLine());
		if (entity != null) {
			logger.debug(TempDb.tix + ":  Get ResponseContentEncoding():" + entity.getContentEncoding());
			logger.debug(TempDb.ix + " : Content Length():" + entity.getContentLength());
			length = entity.getContentLength();

			httpclient.close();
		}
		entity = null;
		response = null;
		httpget = null;
		httpclient = null;
		return length;
	}

	/**
	 * </br>
	 * 查询网络文件大小 </br>
	 * 将书籍大小,名称,编号,下载地址保存到Epub表 </br>
	 * 使用CloseableHttpClient请求网络默认超时时间 </br>
	 * 方法使用注解 连接池myExecutor 在KindleDownApplication.java配置
	 * 
	 * @author eruca
	 * @param path
	 *            网络文件http地址
	 * @param id
	 *            起点书籍编号
	 * @param name
	 *            起点书籍名称
	 * @return 无返回
	 * @exception IOException
	 *                请求网络访问需要上抛异常
	 * 
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
	public void getUrlFileLengthSaveEpub(String path, int id, String name) throws IOException {
		long fileLength = getFileLength(path);
		if (fileLength == 0)
			return;
		Epub onew = new Epub();
		onew.setId(id);
		onew.setUrl(path);
		onew.setName(name);
		onew.setSize(fileLength);
		dao.save(onew);
	}

	public String htmlRead(String path, String fiter) {
		Document doc;
		try {
			doc = Jsoup.connect(path).get();
			Elements elements = doc.select("a[href=\"" + fiter + "\"]");
			return elements.text();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// name="keywords"
		// content
		return "400";

	}

	/**
	 * 定时任务使用方法 <br>
	 * 作用:使用Jsoup 抓取起点强推往期网页,并保存到Epub表中 <br>
	 * https://www.qidian.com/book/strongrec </br>
	 * 解析页面内容: </br>
	 * 查找a[data-bid] 元素文件List集合 遍历集合 组合成
	 * "http://download.qidian.com/epub/"+type.attr("data-bid")
	 * 调用this.getUrlFileLengthSaveEpub 请求网络 </br>
	 * 因需要请求网络需要上报IOException异常
	 * 
	 * @author eruca
	 * @param 无参数
	 * @return 无返回
	 * @exception IOException
	 */
	public void startStrongrecRead() throws IOException {

		Document doc;
		try {
			doc = Jsoup.connect("https://www.qidian.com/book/strongrec").get();
			Elements elements = doc.select("a[data-bid]");
			for (int i = 0; i < elements.size(); i++) {
				Element type = elements.get(i);
				try {
					getUrlFileLengthSaveEpub("http://download.qidian.com/epub/" + type.attr("data-bid") + ".epub",
							Integer.valueOf(type.attr("data-bid")), type.attr("title"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 定时任务使用方法 <br>
	 * 作用:使用Jsoup 抓取起点三江往期网页,并保存到Epub表中 <br>
	 * https://www.qidian.com/book/sanjiang </br>
	 * 解析页面内容: </br>
	 * 查找a[data-bid] 元素文件List集合 遍历集合 组合成
	 * "http://download.qidian.com/epub/"+type.attr("data-bid")
	 * 调用this.getUrlFileLengthSaveEpub 请求网络 </br>
	 * 因需要请求网络需要上报IOException异常
	 * 
	 * @author eruca
	 * @param 无参数
	 * @return 无返回
	 * @exception IOException
	 */
	public void startSanjiangRead() throws IOException {

		Document doc;
		try {
			doc = Jsoup.connect("https://www.qidian.com/book/sanjiang").get();
			Elements elements = doc.select("a[data-bid]");
			for (int i = 0; i < elements.size(); i++) {
				Element type = elements.get(i);
				try {
					getUrlFileLengthSaveEpub("http://download.qidian.com/epub/" + type.attr("data-bid") + ".epub",
							Integer.valueOf(type.attr("data-bid")), type.attr("title"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 查询epub表file为空的数据 通过网络查询下载并回写epub file
	 * 
	 */
	public void getMate() {
		Iterator<Epub> epublist = dao.queryNotNameAll().iterator();
		while (epublist.hasNext()) {
			Epub obj = epublist.next();
			String name = htmlRead("https://book.qidian.com/info/" + obj.getId(),
					"//book.qidian.com/info/" + obj.getId());
			obj.setName(name);
			dao.save(obj);
		}

	}

	/**
	 * 查询出没有书名的书籍编号, 通过网络查询书名并会写Epub表
	 * 
	 */
	public void getFileTasks() {
		// TODO Auto-generated method stub
		dao.queryNotFileAll().forEach((obj)->{
			String file = "";
			try {
				file = downFile(obj.getUrl(), obj.getId() + ".epub");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			obj.setFile(file);
			dao.save(obj);
			
		});
	}

	/**
	 * 下载文件
	 * 
	 * @param url
	 * @param destFileName
	 *            xxx.jpg/xxx.png/xxx.txt
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public String downFile(String url, String destFileName) throws IOException {
		String str = null;
		// 生成一个httpclient对象
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpGet httpget = new HttpGet(url);
		HttpResponse response = httpclient.execute(httpget);
		HttpEntity entity = response.getEntity();
		if (entity != null) {
			InputStream in = entity.getContent();
			File file = new File(destFileName);
			try {
				FileOutputStream fout = new FileOutputStream(file);
				int l = -1;
				byte[] tmp = new byte[1024];
				while ((l = in.read(tmp)) != -1) {
					fout.write(tmp, 0, l);
					// 注意这里如果用OutputStream.write(buff)的话，图片会失真，大家可以试试
				}
				fout.flush();
				fout.close();
				str = file.getPath();
				logger.debug(file.getPath() + "下载成功");
			} finally {
				// 关闭低层流。
				in.close();
			}
		}
		httpclient.close();
		return str;
	}

	/**
	 * 定时任务使用方法 <br>
	 * 作用:使用Jsoup 抓取起点三江往期网页,并保存到Epub表中 <br>
	 * https://www.qidian.com/book/coverrec </br>
	 * 解析页面内容: </br>
	 * 查找a[data-bid] 元素文件List集合 遍历集合 组合成
	 * "http://download.qidian.com/epub/"+type.attr("data-bid")
	 * 调用this.getUrlFileLengthSaveEpub 请求网络 </br>
	 * 因需要请求网络需要上报IOException异常
	 * 
	 * @author eruca
	 * @param 无参数
	 * @return 无返回
	 * @exception IOException
	 */
	public void taskCoverrecRead() throws IOException {
		// TODO Auto-generated method stub
		Document doc;
		try {
			doc = Jsoup.connect("https://www.qidian.com/book/coverrec").get();
			Elements elements = doc.select(".focus-img");
			for (int i = 0; i < elements.size(); i++) {
				Element type = elements.get(i).parent();
				String img = type.select("img").get(0).attr("src");
				String title = type.select("[title]").get(0).attr("title");
				String url = type.select("[title]").get(0).attr("href");
				int id = Integer.valueOf(url.replace("https://book.qidian.com/info/", ""));
				try {
					getUrlFileLengthSaveEpub("http://download.qidian.com/epub/" + id + ".epub", id, title, img);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * </br>
	 * 查询网络文件大小 </br>
	 * 将书籍大小,名称,编号,下载地址保存到Epub表 </br>
	 * 使用CloseableHttpClient请求网络默认超时时间 </br>
	 * 方法使用注解 连接池myExecutor 在KindleDownApplication.java配置
	 * 
	 * @author eruca
	 * @param path
	 *            网络文件http地址
	 * @param id
	 *            起点书籍编号
	 * @param name
	 *            起点书籍名称
	 * @return 无返回
	 * @exception IOException
	 *                请求网络访问需要上抛异常
	 * 
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
	public void getUrlFileLengthSaveEpub(String path, int id, String name, String img) throws IOException {
		long fileLength = getFileLength(path);
		if (fileLength == 0)
			return;
		Epub onew = new Epub();
		onew.setId(id);
		onew.setUrl(path);
		onew.setName(name);
		onew.setSize(fileLength);
		onew.setImg(img);
		dao.save(onew);
		logger.debug(id + ":OK");
	}

	/**
	 * 定时任务使用方法 <br>
	 * 作用:使用Jsoup 抓取起点强推往期网页,并保存到Epub表中 <br>
	 * https://www.qidian.com/book/strongrec </br>
	 * 解析页面内容: </br>
	 * 查找a[data-bid] 元素文件List集合 遍历集合 组合成
	 * "http://download.qidian.com/epub/"+type.attr("data-bid")
	 * 调用this.getUrlFileLengthSaveEpub 请求网络 </br>
	 * 因需要请求网络需要上报IOException异常
	 * 
	 * @author eruca
	 * @param 无参数
	 * @return 无返回
	 * @exception IOException
	 */
	public void startStrongrecReadTest(int page) throws IOException {
		TempDb.ttxn = 2;
		Document doc;
		try {
			doc = Jsoup.connect("https://www.qidian.com/book/strongrec?page=" + page).get();
			Elements elements = doc.select("a[data-bid]");
			for (int i = 0; i < elements.size(); i++) {
				Element type = elements.get(i);
				try {
					getUrlFileLengthSaveEpub("http://download.qidian.com/epub/" + type.attr("data-bid") + ".epub",
							Integer.valueOf(type.attr("data-bid")), type.attr("title"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 定时任务使用方法 <br>
	 * 作用:使用Jsoup 抓取起点三江往期网页,并保存到Epub表中 <br>
	 * https://www.qidian.com/book/sanjiang </br>
	 * 解析页面内容: </br>
	 * 查找a[data-bid] 元素文件List集合 遍历集合 组合成
	 * "http://download.qidian.com/epub/"+type.attr("data-bid")
	 * 调用this.getUrlFileLengthSaveEpub 请求网络 </br>
	 * 因需要请求网络需要上报IOException异常
	 * 
	 * @author eruca
	 * @param 无参数
	 * @return 无返回
	 * @exception IOException
	 */
	public void startSanjiangReadTest(int page) throws IOException {
		TempDb.ttxn = 1;
		Document doc;
		try {
			doc = Jsoup.connect("https://www.qidian.com/book/sanjiang?page=" + page).get();
			Elements elements = doc.select("a[data-bid]");
			for (int i = 0; i < elements.size(); i++) {
				Element type = elements.get(i);
				try {
					getUrlFileLengthSaveEpub("http://download.qidian.com/epub/" + type.attr("data-bid") + ".epub",
							Integer.valueOf(type.attr("data-bid")), type.attr("title"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 定时任务使用方法 <br>
	 * 作用:使用Jsoup 抓取起点三江往期网页,并保存到Epub表中 <br>
	 * https://www.qidian.com/book/coverrec </br>
	 * 解析页面内容: </br>
	 * 查找a[data-bid] 元素文件List集合 遍历集合 组合成
	 * "http://download.qidian.com/epub/"+type.attr("data-bid")
	 * 调用this.getUrlFileLengthSaveEpub 请求网络 </br>
	 * 因需要请求网络需要上报IOException异常
	 * 
	 * @author eruca
	 * @param 无参数
	 * @return 无返回
	 * @exception IOException
	 */
	public void taskCoverrecReadTest(int page) throws IOException {
		// TODO Auto-generated method stub
		TempDb.ttxn = 3;
		Document doc;
		try {
			doc = Jsoup.connect("https://www.qidian.com/book/coverrec?page=" + page).get();
			Elements elements = doc.select(".focus-img");
			for (int i = 0; i < elements.size(); i++) {
				try {
					Element type = elements.get(i).parent();
					String img = type.select("img").get(0).attr("src");
					String title = type.select("[title]").get(0).attr("title");
					String url = type.select("[title]").get(0).attr("href");
					int id = Integer.parseInt(url.replace("//book.qidian.com/info/", "").replace("http:", "")
							.replace("https:", "").trim());

					getUrlFileLengthSaveEpub("http://download.qidian.com/epub/" + id + ".epub", id, title, img);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void EpubToTask() {
		// TODO Auto-generated method stub
		dao.queryFileAllNotTo().parallelStream().forEachOrdered((obj) ->{
			try {
			String rem;

			rem = epubToDao.FileEpubToMobi(obj.getId(), obj.getName());
			logger.debug(rem);
			obj.setRem(rem);
			dao.save(obj);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		});
		 

	}

	public void getMobiSendKindleEmail() {
		// TODO Auto-generated method stub
		mobidao.queryNotSend().forEach((obj) -> {
			try {
				int send = epubToDao.FileMiblieSendeMail(obj.getId(), obj.getName());
				obj.setSend(send);
				mobidao.save(obj);
				logger.debug("已发送email" + obj.getName());
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		});
	}

	public void deleteFileTasks() {
		// TODO Auto-generated method stub
		dao.queryFileNotIO().forEach((obj) -> {
			File file = new File(obj.getFile());
			if (file.exists())
				file.delete();
			obj.setFile(null);
			obj.setRem(null);
			dao.save(obj);
			
		});
		
		dao.queryFileYesIO().forEach((obj) -> {
			File file = new File(obj.getFile());
			if (file.exists())
				file.delete();
		});
		 
	}

	@Value("${matenum}")
	private static int matenum;

	public void taskMOblieMateRead() {
		// TODO Auto-generated method stub
		Document doc;
		try {
			++matenum;
		    logger.debug("参数matenum为：{}", matenum);  
			doc = Jsoup.connect(
					"https://m.qidian.com/majax/recommend/strongreclist?_csrfToken=2IZiWA6rnNeJt6JRTGQJKcgSg8S1dhOkMVKekLSI&gender=male&pageNum="
							+ matenum)
					.get();
			Elements elements = doc.getAllElements();
			logger.debug(elements.get(0).text());
			JSONObject objx = JSONObject.parseObject(elements.get(0).text());
			if (objx.getIntValue("code") != 0) {
				matenum = 0;
				return;
			}
			JSONArray arrys = objx.getJSONObject("data").getJSONArray("records");
			arrys.forEach((e) -> {
				JSONObject nbjk = (JSONObject) e;
				logger.debug("{}", nbjk); 
				System.out.println(nbjk);
				Epub obj = new Epub();
				obj.setId(nbjk.getIntValue("bid"));
				obj.setUrl("http://download.qidian.com/epub/"+nbjk.getIntValue("bid")+".epub");
				obj.setName(nbjk.getString("bName"));
				obj.setRec(nbjk.getString("rec"));
				obj.setCatId(nbjk.getString("catId"));
				obj.setCat(nbjk.getString("cat"));
				obj.setCnt(nbjk.getString("cnt"));
				obj.setState(nbjk.getString("state"));
				obj.setbAuth(nbjk.getString("bAuth"));
				dao.save(obj);
			
			});
			logger.debug("{}",arrys.size());
			// doc2 =
			// Jsoup.connect("https://m.qidian.com/majax/recommend/hotFreelist?_csrfToken=2IZiWA6rnNeJt6JRTGQJKcgSg8S1dhOkMVKekLSI&gender=male&pageNum=3").get();
			// elements=doc2.getAllElements();
			// obj=new JSONObject().parseObject(elements.get(0).text());
			// arrys=obj.getJSONObject("data").getJSONArray("records");
			// for (int i = 0; i <arrys.size(); i++) {
			// JSONObject nbjk=arrys.getJSONObject(i);
			// logger.debug(nbjk);
			// }
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}